#include <rtthread.h>
#include <rthw.h>
#include "board.h"
#include "nuc970_sys.h"

void rt_hw_console_output(const char *str)
{
    sysPutString((INT8 *)str);
}

void rt_hw_console_flush()
{
    sysUartFlush();
}

int print_clock_info(void)
{
    int apll_clk, upll_clk, Fvco_clk, sys_clk, cpu_clk, dram_clk, pclk, hclk1_clk, hclk234_clk, usbh_clk;
    int reg_value, sys_sel, CPU_N, N, M, P, PCLK_N, HCLK234_N, USB_N, USB_S;

    reg_value = inpw(REG_CLK_APLLCON);
    N = (reg_value&0x7f)+1;
    M = ((reg_value>>7)&0x3f) + 1;
    P = ((reg_value>>13) & 0x07) + 1;
    apll_clk = 12*(N/(M*P));

    reg_value = inpw(REG_CLK_UPLLCON);
    N = (reg_value&0x7f)+1;
    M = ((reg_value>>7)&0x3f) + 1;
    P = ((reg_value>>13) & 0x07) + 1;
    upll_clk = 12*(N/(M*P));

    Fvco_clk = 12*(N/M);

    rt_kprintf("xin-clk:12MHz, apll-clk:%dMHz, upll-clk:%dMHz, Fvco_clk:%dMHz.\n",
                apll_clk, upll_clk, Fvco_clk);

    reg_value = inpw(REG_CLK_DIVCTL0);
    sys_sel = (reg_value>>3)&0x03;
    if (sys_sel == 2) { //Apll-clk
        sys_clk = apll_clk;
    } else if (sys_sel == 3) { //Upll-clk
        sys_clk = upll_clk;
    } else {
        sys_clk = 12; 
    }

    sys_clk = sys_clk/((reg_value&0x07)+1);

    CPU_N = ((reg_value>>16)&0x0f);
    cpu_clk = sys_clk / (CPU_N+1);

    PCLK_N = (reg_value>>24) & 0x0f;
    pclk = cpu_clk/2/(PCLK_N+1);

    dram_clk = cpu_clk/2;
    hclk1_clk = cpu_clk/2;

    HCLK234_N = (reg_value>>20) & 0x0f;
    hclk234_clk = hclk1_clk/(HCLK234_N+1);

    rt_kprintf("sys-clk:%dMHz, cpu-clk:%dMHz, dram_clk:%dMHz, pclk:%dMHz, hclk1_clk:%dMHz, hclk234_clk:%dMHz.\n",\
                sys_clk, cpu_clk, dram_clk, pclk, hclk1_clk, hclk234_clk);

    reg_value = inpw(REG_CLK_DIVCTL2);
    USB_N = (reg_value>>8) & 0x0f;
    USB_S = (reg_value>>3) & 0x03;
    usbh_clk = hclk234_clk / (USB_N+1);

    rt_kprintf("usbh-clk:%dMHz, usbh-n:%d, usbh-s:%d.\n",
               usbh_clk, USB_N, USB_S);

    return RT_EOK;
}
INIT_APP_EXPORT(print_clock_info);
